package server;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author oyz
 * Minicat的主类
 */
public class Bootstrap {
    /**
     * 定义socket监听端口
     */
    private int port = 8080;

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }


    private Map<String,HttpServlet> servletMap = new HashMap<>();

    /**
     * Minicat启动需要初始化展开的一些操作
     */
    public void start() throws IOException {
        ServerSocket  socket = new ServerSocket(port);
        while(true){
            Socket accept = socket.accept();
            OutputStream outputStream = accept.getOutputStream();
            String data = "Hello MiniCat!";
            String str = HttpProtocolUtil.getHttpHeader200(data.getBytes().length)+data;
            outputStream.write(str.getBytes());
            accept.close();
        }
    }

    /**
     * Minicat 3.0版本
     * 需求: 解析动态资源文件(Servlet)
     */
    public String start3() throws Exception {
        // 加载解析相关配置 web.xml 初始化Servlet
        loadServlet();
        ServerSocket socket = new ServerSocket(8080);
        System.out.println("socket 启动了...");

        while(true){
            Socket accept = socket.accept();
            InputStream inputStream = accept.getInputStream();
            Request request = new Request(inputStream);
            Response response = new Response(accept.getOutputStream());

            // 静态资源处理
            if(servletMap.get(request.getUrl())==null){
                response.outPut(request.getUrl());
            }else{
                // 动态资源servlet的请求
                HttpServlet httpServlet = servletMap.get(request.getUrl());
                httpServlet.service(request,response);
            }
            accept.close();
        }

    }



    private void loadServlet() {
        InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("web.xml");
        SAXReader saxReader = new SAXReader();
        try {
            Document read = saxReader.read(resourceAsStream);
            Element rootElement = read.getRootElement();
            List<Element> list = rootElement.selectNodes("//sevlet");
            for (int i = 0; i < list.size(); i++) {
                Element element = list.get(i);
                Element servletNameElememt = (Element) element.selectSingleNode("servlet-name");
                //  <servlet-name>lagou</servlet-name>
                String servletName = servletNameElememt.getStringValue();
                Element servletClassElememt = (Element) element.selectSingleNode("servlet-class");
                //   <servlet-class>server.LagouServlet</servlet-class>
                String servletClass = servletClassElememt.getStringValue();

                // 根据servlet-name的值来获取到url-pattern的值
                Element servletMapping = (Element) rootElement.selectSingleNode("/web-app/servlet-mapping[servlet-name='" + servletName + "']");
                //  /lagou
                String urlPattern = servletMapping.selectSingleNode("url-pattern").getStringValue();
                servletMap.put(urlPattern, (HttpServlet) Class.forName(servletClass).newInstance());

            }
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }

    }

    /**
     * Minicat 2.0版本
     * 需求: 完成Request和Response对象，返回html的静态文件
     */
    public String start2() throws IOException{
        ServerSocket socket = new ServerSocket(8080);
        System.out.println("socket 启动了...");
          /*  while (true){
                Socket accept = socket.accept();
                InputStream inputStream = accept.getInputStream();
                // 从流中获取请求信息
                int count = 0;
                while(count==0){
                     count = inputStream.available();
                }
                byte[] bytes = new byte[count];
                inputStream.read(bytes);
                System.out.println("=========>>>请求信息:"+new String(bytes));
                accept.close();
            }*/
        while(true){
            Socket accept = socket.accept();
            InputStream inputStream = accept.getInputStream();
            Request request = new Request(inputStream);
            Response response = new Response(accept.getOutputStream());
            response.outputHtml(request.getUrl());
            accept.close();
        }

    }




    /**
     * 程序入口
     * @param args
     */
    public static void main(String[] args) {
        try {
            new Bootstrap().start2();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
